/**
 * 导入vite模块
 */
import { defineConfig, loadEnv } from 'vite';

/**
 * 导入vite插件
 */
import vue from '@vitejs/plugin-vue';
import legacy from '@vitejs/plugin-legacy';
import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
import viteCompression from 'vite-plugin-compression';
import autoprefixer from 'autoprefixer';

/**
 * 导入elementplus的解析器
 */
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';

/**
 * 导入node模块
 */
import { resolve } from 'path';

/**
 * 导入类型声明
 */
import type { ConfigEnv, UserConfig } from 'vite';

/**
 * 导出vite配置
 */
export default defineConfig((env: ConfigEnv) => {
  /**
   * 获取当前时间戳
   */
  const timestamp: number = new Date().getTime();

  /**
   * 获取环境变量信息
   */
  const envConfig: Record<string, string> = loadEnv(env.mode, resolve(process.cwd()));

  /**
   * 打印当前环境变量
   */
  console.log(`当前vite运行环境: ${envConfig.VITE_NODE_ENV}`);
  console.log(`当前环境变量: ${envConfig.VITE_ENV}`);

  /**
   * 配置信息
   */
  const config: UserConfig = {
    /**
     * 环境变量目录
     */
    envDir: resolve(process.cwd(), './'),

    /**
     * 静态资源服务的文件夹
     */
    publicDir: resolve(process.cwd(), './public'),

    /**
     * 基地址
     */
    base: './',

    /**
     * 设置别名
     */
    resolve: {
      alias: {
        '@': resolve(process.cwd(), './src'),
      },
      extensions: ['.vue', '.js', '.scss', '.css', '.mjs', '.ts'],
    },

    /**
     * scss配置
     */
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: `@use '@/assets/element-plus/index.scss' as *;`,
        },
      },
      postcss: {
        plugins: [autoprefixer()],
      },
    },

    /**
     * 插件
     */
    plugins: [
      /**
       * vue插件
       */
      vue(),

      /**
       * 兼容性插件
       */
      legacy({
        targets: [
          '> 1%, last 1 version, ie >= 11',
          'safari >= 10',
          'Android > 39',
          'Chrome >= 60',
          'Safari >= 10.1',
          'iOS >= 10.3',
          'Firefox >= 54',
          'Edge >= 15',
        ],
        additionalLegacyPolyfills: ['regenerator-runtime/runtime'],
        polyfills: ['es.promise.finally', 'es/map', 'es/set', 'es.object.from-entries'],
        modernPolyfills: true,
        renderLegacyChunks: true,
      }),

      /**
       * 自动导入模块
       */
      AutoImport({
        imports: ['vue', 'vue-router', 'pinia'],
        resolvers: [
          ElementPlusResolver({
            importStyle: 'sass',
          }),
        ],
        dts: resolve(process.cwd(), './auto-imports.d.ts'),
      }),

      /**
       * 配置组件库
       */
      Components({
        dirs: [resolve(process.cwd(), './src/components')],
        resolvers: [
          ElementPlusResolver({
            importStyle: 'sass',
          }),
        ],
        dts: resolve(process.cwd(), './components.d.ts'),
      }),

      /**
       * 开启gzip压缩
       */
      viteCompression({
        verbose: true,
        disable: false,
        threshold: 10240,
        algorithm: 'gzip',
        ext: '.gz',
      }),
    ],

    /**
     * 服务配置
     */
    server: {
      /**
       * 端口号
       */
      port: 8082,

      /**
       * 热更新
       */
      hmr: true,
    },

    /**
     * 打包配置
     */
    build: {
      /**
       * 打包前清空dist目录
       */
      emptyOutDir: true,

      /**
       * 输出目录
       */
      outDir: resolve(process.cwd(), './dist'),

      /**
       * 打包文件超出预警
       */
      chunkSizeWarningLimit: 1500,

      /**
       * rollup配置
       */
      rollupOptions: {
        // 输出
        output: {
          // 引入文件名的名称
          chunkFileNames: `js/[name]-[hash]${timestamp}.js`,
          // 包的入口文件名称
          entryFileNames: `js/[name]-[hash]${timestamp}.js`,
          // 资源文件像 字体，图片等
          assetFileNames: `assets/[ext]/[name]-[hash]${timestamp}.[ext]`,
          // 配置代码分割
          manualChunks(id) {
            if (id.includes('node_modules')) {
              return id.toString().split('node_modules/')[1].split('/')[0].toString();
            }
          },
        },
      },
    },
  };

  /**
   * 导出配置
   */
  return config;
});
